package brad.zimmerman.dungeon.game;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

//This class creates them main map that the character will be navigating
//Also stores the current coordinates of the player
public class ClassCreateMap {
	Random random = new Random(System.currentTimeMillis());
	public int[][] map;
	public int pStartX;
	public int pStartY;
	ClassCreateMap(int Dim){
		//This ensures that the character does not start out on the edges of the map
		pStartX = random.nextInt( Dim-2 );
		pStartY = random.nextInt( Dim-2 );
		pStartX += 1;
		pStartY += 1;
		map = new int [Dim][Dim];
		int plot;
		List<coorObject> trail = new ArrayList<coorObject>();
		Integer[] direction = new Integer[]{0, 1, 2, 3};
		coorObject holder;
		
		for(int y = 0; y< Dim; y++){
			for (int x=0; x<Dim; x++){
				this.map[x][y]= 1;
			}
		}
		
		//This is the point where the player starts
		
		trail.add(new coorObject(pStartX, pStartY));
		
		//Uses kruskal's algorithm to generate a random navigable map
		while (!trail.isEmpty()){
			//Picks a random wall to branch the trail out at
			plot = random.nextInt( trail.size() );
			holder = trail.get(plot);
			this.map[holder.getX()][holder.getY()]= 0;

			// Shuffle the elements in the array
			//This is to make sure that the roads twist, and
			//are not straight corridors after generation
			Collections.shuffle(Arrays.asList(direction));
			//If this direction is in the map
			for (int road : direction){
				if (road == 0){
					if (holder.getX()-1 != 0)
					{
						//If the next cell over in the same direction is not in the maze
						if (checkWall(holder.getX()-2, holder.getY(), Dim)){
							//Mark the cell in between as a transition, and the next cell as part of maze 
							this.map[holder.getX()-1][holder.getY()]= 0;
							this.map[holder.getX()-2][holder.getY()]= 0;
							trail.add(new coorObject(holder.getX()-2, holder.getY()));
						}
					}
				}
				if (road == 1){
					if (holder.getY()+1 != Dim-1)
					{
						if (checkWall(holder.getX(), holder.getY()+2, Dim)){
							this.map[holder.getX()][holder.getY()+1]= 0;
							this.map[holder.getX()][holder.getY()+2]= 0;
							trail.add(new coorObject(holder.getX(), holder.getY()+2));
						}
					}
				}
				if (road == 2){
					if (holder.getX()+1 != Dim-1)
					{
						if (checkWall(holder.getX()+2, holder.getY(), Dim)){
							this.map[holder.getX()+1][holder.getY()]= 0;
							this.map[holder.getX()+2][holder.getY()]= 0;
							trail.add(new coorObject(holder.getX()+2, holder.getY()));
						}
					}
				}
				if (road == 3){
					if (holder.getY()-1 != 0)
					{
						if (checkWall(holder.getX(), holder.getY()-2, Dim)){
							this.map[holder.getX()][holder.getY()-1]= 0;
							this.map[holder.getX()][holder.getY()-2]= 0;
							trail.add(new coorObject(holder.getX(), holder.getY()-2));
						}
					}
				}
			}
			trail.remove(plot);
			
		}
		
		map[pStartX-1][pStartY-1] = 0;
		map[pStartX][pStartY-1] = 0;
		map[pStartX+1][pStartY-1] = 0;
		map[pStartX-1][pStartY] = 0;
		map[pStartX+1][pStartY] = 0;
		map[pStartX-1][pStartY+1] = 0;
		map[pStartX][pStartY+1] = 0;
		map[pStartX+1][pStartY+1] = 0;
		
		for(int i = 0; i < 10;){
			int selectorX = random.nextInt( Dim-2 );
			int selectorY = random.nextInt( Dim-2 );
			if (map[selectorX+1][selectorY+1] == 1){
				map[selectorX+1][selectorY+1] = 0;
				i++;
			}
		}
		
		//for(int y=0;y<Dim;y++){
		//	for(int x=0;x<Dim;x++){
		//		int randomIndex = random.nextInt( 2 );
		//		this.map[x][y]= randomIndex;
		//	}
		//}
	}
	ClassCreateMap(boolean tutorial){
		int[][] mapTemplate = {
				{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0}, //0
				{0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0}, //1
				{0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0}, //2
				{1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0}, //3
				{0,0,0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0}, //4
				{0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0}, //5
				{0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,0,1}, //6
				{1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0}, //7
				{0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, //8
				{0,0,1,0,0,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1}, //9
				{0,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, //10
				{0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, //11
				{1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,1,1,0}, //12
				{0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,0,0}, //13
				{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0}, //14
				{0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0}, //15
				{1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0}, //16
				{0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0}, //17
				{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0}, //18
				{0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0}  //19
		};    // 0.1.2.3.4.5.6.7.8.9.10111213141516171819
		
		map = new int[20][20];
		for(int y = 0; y < 20; y++){
			for(int x = 0; x< 20; x++){
				map[y][x] = mapTemplate[x][y];
			}
		}
		
		pStartX = 1;
		pStartY = 1;
		
	}
	//This helps to keep track of the coordinates that are used
	//to make the path on the map
	class coorObject {
		int x;
		int y;
		coorObject(int x, int y){
			this.x = x;
			this.y = y;
		}
		int getX(){
			return x;
		}
		int getY(){
			return y;
		}
	}
	public boolean checkWall(int X, int Y, int Dim){
		if ((X >= 0) && (Y >= 0) && (X<Dim) && (Y<Dim)){
			if (this.map[X][Y]== 1){
			//The next cell over is not a path nor outside of the map
				return true;
			}
		}
		return false;
	}
	public int getPlayerX(){return pStartX;}
	public int getPlayerY(){return pStartY;}
	public void setPlayerX(int X){pStartX = X;}
	public void setPlayerY(int Y){pStartY = Y;}
	public int returnCellValue(int X, int Y){return this.map[X][Y];}
	public int[][] returnMap(){return this.map;}
}
